
package cn.zlg.common.datadump.condition;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.ComparableExpressionBase;
import com.querydsl.core.types.dsl.EntityPathBase;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class QueryFieldCondition {
    private String queryParamName;

    // 如果直接查询的非主表字段，给出对应主表的哪个字段
    private ComparableExpressionBase mainEntityProperty;

    private EntityPathBase refEntity;
    // 关联查询时，用于和主表关联字段匹配的字段
    private ComparableExpressionBase refEntityKey;
    private ComparableExpressionBase refEntityProperty;

    private String condition;

    /**
     * 自定义查询条件构建，用于特别复杂的场景
     */
    private CustomQueryConditionBuilder customQueryConditionBuilder;
    /**
     * 从Expression中反射获取的条件方法
     */
    private Method conditionMethod;

    public QueryFieldCondition(String queryParamName, EntityPathBase refEntity,
            ComparableExpressionBase refEntityProperty, ComparableExpressionBase refEntityKey,
            ComparableExpressionBase mainEntityProperty, String condition) {
        super();
        this.queryParamName = queryParamName;
        this.mainEntityProperty = mainEntityProperty;
        this.refEntity = refEntity;
        this.refEntityProperty = refEntityProperty;
        this.condition = condition;
        this.refEntityKey = refEntityKey;
    }

    public QueryFieldCondition(String queryParamName, EntityPathBase refEntity,
            ComparableExpressionBase refEntityProperty, ComparableExpressionBase refEntityKey, String condition) {
        super();
        this.queryParamName = queryParamName;
        this.refEntity = refEntity;
        this.refEntityProperty = refEntityProperty;
        this.condition = condition;
        this.refEntityKey = refEntityKey;
    }

    public QueryFieldCondition(String queryParamName, EntityPathBase refEntity,ComparableExpressionBase refEntityProperty,
                               CustomQueryConditionBuilder builder, String condition) {
        super();
        this.queryParamName = queryParamName;
        this.refEntity = refEntity;
        this.refEntityProperty = refEntityProperty;
        this.customQueryConditionBuilder = builder;
        this.condition = condition;
    }

    public Predicate buildPredicate(Object value) throws Exception {
        if(customQueryConditionBuilder!=null) {
            return customQueryConditionBuilder.build(queryParamName, refEntityProperty, value);
        }
        if (conditionMethod.getParameterCount() == 0) {
            return (Predicate) conditionMethod.invoke(refEntityProperty);
        } else {
            return (Predicate) conditionMethod.invoke(refEntityProperty,value);
        }
    }

}

